package ru.ifmo.swing.genetics.termination;

import org.uncommons.watchmaker.framework.PopulationData;
import org.uncommons.watchmaker.framework.TerminationCondition;
import ru.ifmo.swing.EvolutionControlWithConfigProvider;
import ru.ifmo.swing.genetics.config.common.MultiChooser;

import javax.swing.*;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * Terminates IF ANY of conditions is true
 *
 * @author avhaliullin
 */
public class TerminateConditionsChooser implements TerminationCondition, EvolutionControlWithConfigProvider {
    private final MultiChooser<TerminationCondition> control;
    private List<TerminationCondition> baseConditions;

    public TerminateConditionsChooser(Map<String, TerminationCondition> options) {
        control = new MultiChooser<TerminationCondition>(options);
    }

    public void setBaseConditions(List<TerminationCondition> baseConditions) {
        this.baseConditions = baseConditions;
    }

    public boolean shouldTerminate(PopulationData<?> populationData) {
        if (baseConditions != null) {
            for (TerminationCondition terminationCondition : baseConditions) {
                if (terminationCondition.shouldTerminate(populationData)) {
                    return true;
                }
            }
        }
        for (TerminationCondition terminationCondition : control.getItems()) {
            if (terminationCondition.shouldTerminate(populationData)) {
                return true;
            }
        }
        return false;
    }

    public JComponent getControl() {
        return control;
    }

    public void reset() {
        control.reset();
    }

    public void setDescription(String description) {
        control.setTitle(description);
    }

    public Map<String, Object> getParamValues() {
        Map<String, Object> res = new TreeMap<String, Object>();
        List items = control.getItems();
        int index = 0;
        for (Object item : items) {
            res.put("Selected operator #" + index++, item);
        }
        return res;
    }
}
